package com.wxmit.framework.web.config;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.wxmit.framework.web.intercepter.LogTraceInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @author by huangxiong
 * @Description webMvc配置
 * @Date 2020/7/31 12:01
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {


    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 拦截器注册
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // log trace
        registry.addInterceptor(new LogTraceInterceptor());
    }



    /**
     *  这里需要注意，因为默认的convert是String，如果方法返回的是String，那么将会被提前返回，所以需要做一下兼容。
     * @param converters
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new StringOrMappingJackson2HttpMessageConverter(objectMapper));

        //   super.extendMessageConverters(converters);
    }

    /**
     *  所有请求，所有域都支持跨域
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路由
        registry.addMapping("/**")
                // 设置允许跨域请求的域名
                .allowedOriginPatterns("*")
                // 是否允许证书（cookies）
                .allowCredentials(true)
                // 设置允许的方法
                .allowedMethods("*")
                .allowedHeaders("*")
                // 跨域允许时间
                .maxAge(3600);
    }

//    @Override
//    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        /** 本地文件上传路径 */
//        registry.addResourceHandler(ShushanFileConfig.urlPrefix + "/**").addResourceLocations("file:" + ShushanFileConfig.baseDir + "/");
//    }

    /**
     * 兼容String和对象类型
     *
     * @author Wang.ch
     * @date 2019/12/12
     */
    public static class StringOrMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {

        private static final StringHttpMessageConverter shmc = new StringHttpMessageConverter();

        public StringOrMappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
            super();
            setObjectMapper(objectMapper);
        }

        @Override
        public boolean canWrite(Class<?> clazz, MediaType mediaType) {
            boolean canWrite = super.canWrite(clazz, mediaType);
            if (!canWrite) {
                canWrite = clazz.isAssignableFrom(String.class);
            }
            return canWrite;
        }

        @Override
        protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
                throws IOException, HttpMessageNotWritableException {
            if (object != null && object instanceof String) {
                //  outputMessage.getHeaders().setContentType(MediaType.TEXT_PLAIN);
                shmc.write((String)object, MediaType.TEXT_PLAIN, outputMessage);
                return;
            }
            //  outputMessage.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
            super.writeInternal(object, object != null ? object.getClass() : null, outputMessage);
        }
    }


}
